Skip to content

refactor: migrate Builder & Knowledge Graph to React Flow + dependency refresh - #5

Merged
arvarik merged 1 commit into
mainfrom
feature/react-flow-migration
Aug 17, 2026
Merged

refactor: migrate Builder & Knowledge Graph to React Flow + dependency refresh#5
arvarik merged 1 commit into
mainfrom
feature/react-flow-migration

Conversation

@arvarik

@arvarik arvarik commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces the hand-rolled diagram engines in both graph surfaces with React Flow (@xyflow/react), deletes more code than it adds (−548 net lines), and refreshes the dependency tree (npm audit: 10 vulnerabilities → 0).

🎨 Builder — React Flow canvas

  • Canvas.jsx shrinks from ~570 lines of hand-rolled pan/zoom/drag/edge-drawing to a ~200-line controlled React Flow component.
  • New capabilities for free: minimap with category colors, multi-select box, on-canvas zoom/fit controls, touch support, smooth drag-to-connect from any anchor to any anchor (loose connection mode).
  • Kept behaviors: click an edge to delete it, per-category edge colors with arrowheads, duplicate-edge prevention, drop-from-toolbox, empty-state prompt, auto-save, templates, PNG export, ⌘S, AI Verify.
  • Removed dead UI: the Select/Text/Arrow/Color tool buttons and Undo/Redo did nothing — they had no handlers. They're gone instead of pretending.
  • Node cards widened (168px) with a hover-floating delete button — component names no longer truncate.

🕸️ Knowledge Graph — layered dagre layout

  • The d3-force simulation is replaced by a dagre layered (Sugiyama) layout: every prerequisite sits in an earlier column than its dependents, and crossing minimization keeps edge bundles readable. Learning reads strictly left → right now.
  • Concept nodes are HTML pills (health dot, name, card-count badge, ready/locked/track styling) instead of SVG circles — crisper text, easier theming.
  • Lineage highlighting (prereqs indigo / unlocks teal), search, pillar & readiness filters, learning tracks, and the slide-over panel carry over unchanged.
  • Health-colored minimap + canvas controls for navigating the big map.
  • Dependency swap: d3-force removed; @dagrejs/dagre added.

🔒 Persistence unchanged (zero migration)

The database, templates, and server keep the legacy board shape (x/y, from/to, anchors). The app store holds the React Flow shape; src/components/builder/boardModel.js converts only at the boundaries. Verified live: existing boards load as-is, and a mouse-drawn drag + new connection auto-saved back in the legacy format.

Also fixed along the way: the design system's global img, svg { max-width: 100% } reset collapsed React Flow's edge SVGs to zero width (scoped override + AGENTS.md gotcha), and category colors now derive from BUILDER_COMPONENTS — Resiliency components previously fell back to indigo.

📦 Dependency refresh

Change Detail
Security react-router-dom 7.18.2 (fixes 5 advisories incl. open redirect + DoS), concurrently 10.0.5 (shell-quote DoS), vite 8.2.1 (postcss). Audit: 10 → 0 vulnerabilities
In-range react 19.2.8, mermaid 11.16.1, lucide-react 1.31, zustand 5.0.15, eslint 10.8.1, vitest 4.1.10, and the rest of the wanted column
Majors (each verified) react-markdown 9→10, better-sqlite3 12→13 (native module load + server boot verified), @testing-library/jest-dom 6→7, jsdom 29→30
Added / removed + @xyflow/react 12.11, + @dagrejs/dagre 3.1 · − d3-force
Deliberately skipped katex 0.18 — rehype-katex@7 bundles its own katex ^0.16; bumping the top-level package would desync the loaded CSS from what rehype-katex renders

Bundle cost: +45 KB gzip (561 → 606 KB).

Testing

  • 250 tests, 18 files, all passing; lint and production build clean.
  • vitest.setup.js adds the official React Flow jsdom mocks (DOMMatrixReadOnly, element dimensions, getBBox).
  • Builder tests rewritten from implementation-pixel assertions to behavior: drop → store state (React Flow shape), rendered labels, React Flow chrome, delete cascade.
  • Verified live in Chrome (dark + light themes): board loading, node drag, drawing a connection with real mouse events, 3-second auto-save round-trip into the legacy DB format, edge click-delete, /builder?board= deep link, a 17-node complex board, graph lineage highlighting, node panel, filters, and markdown/mermaid rendering after the react-markdown major.
  • README + docs updated (user-guide, architecture, AGENTS) with fresh Builder and Knowledge Graph screenshots.

🤖 Generated with Claude Code

…dependencies

React Flow migration (net -660 lines):
- Builder canvas rewritten on @xyflow/react: drag-to-connect anchors
  (loose connection mode), click-to-delete edges, Backspace deletion,
  multi-select, minimap with category colors, on-canvas zoom controls,
  and fit-view — replacing ~570 lines of hand-rolled pan/zoom/drag/
  edge-drawing code in Canvas.jsx
- Knowledge Graph rewritten on React Flow + dagre: a layered
  (Sugiyama) left-to-right layout replaces the d3-force simulation,
  so every prerequisite sits in an earlier column than its dependents;
  HTML concept pills replace SVG circles; lineage highlighting,
  filters, tracks, and the slide-over panel carry over unchanged
- Persisted board format is unchanged: the app store now holds the
  React Flow shape and src/components/builder/boardModel.js converts
  at the boundaries (board load/save, templates, export, AI verify);
  existing boards load as-is and auto-save round-trips verified
- Removed dead Builder UI: the non-functional Select/Text/Arrow/Color
  tools and the unwired Undo/Redo buttons
- Consolidated the duplicated icon and category-color maps into
  boardModel.js; category colors now derive from BUILDER_COMPONENTS
  (fixes Resiliency components rendering with the fallback color)
- Fixed: the global 'img, svg { max-width: 100% }' reset collapsed
  React Flow's edge SVGs to zero width (scoped override + gotcha doc)
- Removed dependency: d3-force. Added: @xyflow/react, @dagrejs/dagre

Dependency upgrades (npm audit: 10 vulnerabilities -> 0):
- In-range: react 19.2.8, react-router-dom 7.18.2 (fixes 5 CVEs),
  vite 8.2.1, concurrently 10.0.5 (fixes shell-quote DoS), eslint
  10.8.1, mermaid 11.16.1, lucide-react 1.31, zustand 5.0.15, and the
  rest of the wanted column
- Majors, each verified against the suite: react-markdown 10,
  better-sqlite3 13, @testing-library/jest-dom 7, jsdom 30
- Deliberately skipped: katex 0.18 (rehype-katex@7 bundles its own
  katex ^0.16; a top-level bump would desync CSS from rendering)

Testing:
- vitest.setup.js gains the official React Flow jsdom mocks
  (DOMMatrixReadOnly, element dimensions, SVG getBBox)
- Builder tests rewritten to test behavior (store state, rendered
  labels, React Flow chrome) instead of implementation pixels
- 250 tests pass; verified live in Chrome: board load, node drag,
  drawing a connection by mouse, auto-save persisting the legacy
  format, edge click-delete, deep links, complex 17-node board,
  graph lineage highlighting, node panel, light theme

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@arvarik
arvarik merged commit adb4e0d into main Aug 17, 2026
1 check passed
@arvarik
arvarik deleted the feature/react-flow-migration branch August 17, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant